package com.cskaoyan.aspect;

import com.cskaoyan.annotation.AdminLog;
import com.cskaoyan.bean.Admin;
import com.cskaoyan.bean.Log;
import com.cskaoyan.bean.basebean.BaseRespVo;
import com.cskaoyan.bean.sysmanage.AddAdminBo;
import com.cskaoyan.bean.sysmanage.UpdateAdminBo;
import com.cskaoyan.service.LogService;
import com.cskaoyan.utils.HttpContextUtils;
import com.cskaoyan.utils.IpUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;

@Aspect
@Component
public class LogAspect {

    @Autowired
    LogService logService;

    @Pointcut("@annotation(com.cskaoyan.annotation.AdminLog)")
    public void adminLogPointcut() {

    }

    @Around("adminLogPointcut()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = joinPoint.proceed();
        //记录日志
        recordLog(joinPoint, result);
        return result;
    }

//    @AfterReturning(value = "adminLogPointcut()", returning = "result")
//    public void afterReturning(JoinPoint joinPoint, Object result) {
//        recordLog(joinPoint, result);
//    }

    @AfterThrowing(value = "adminLogPointcut()", throwing = "e")
    public void saveExceptionLog(JoinPoint joinPoint, Throwable e) {
        recordExceptionLog(joinPoint);
    }

    private void recordExceptionLog(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        AdminLog adminLog = method.getAnnotation(AdminLog.class);
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        String ip = IpUtils.getIpAddr(request);
        Log log = new Log();
        Subject subject = SecurityUtils.getSubject();
        PrincipalCollection principals = subject.getPrincipals();
        if (principals == null) {
            log.setAdmin("匿名用户");
        } else {
            Admin admin = (Admin) principals.getPrimaryPrincipal();
            log.setAdmin(admin.getUsername());
        }
        if ("登录".equals(adminLog.action())) {
            log.setResult("用户名或密码错误");
        }
        log.setIp(ip);
        log.setType(adminLog.type());
        log.setAction(adminLog.action());
        //失败
        log.setStatus(false);
        //log.setResult(resultVo.getErrmsg());
        log.setAddTime(new Date());
        log.setUpdateTime(new Date());
        logService.insertLogInfo(log);
    }


    //记录日志
    private void recordLog(JoinPoint joinPoint, Object result) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        AdminLog adminLog = method.getAnnotation(AdminLog.class);
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        String ip = IpUtils.getIpAddr(request);
        Log log = new Log();
        Subject subject = SecurityUtils.getSubject();
        Admin admin = (Admin) subject.getPrincipals().getPrimaryPrincipal();
        log.setAdmin(admin.getUsername());
        log.setIp(ip);
        log.setType(adminLog.type());
        log.setAction(adminLog.action());
        BaseRespVo resultVo = (BaseRespVo) result;
        //失败
        if (resultVo.getErrno() != 0) {
            log.setStatus(false);
            log.setResult(resultVo.getErrmsg());
        } else {
            //成功
            log.setStatus(true);

            Object[] args = joinPoint.getArgs();
            if (adminLog.type() == 2) {
                //log.setResult("");
                Map arg = (Map) args[0];
                Integer orderId = (Integer) arg.get("orderId");
                log.setResult("订单编号：" + orderId);
            } else if ("添加管理员".equals(adminLog.action())) {
                AddAdminBo adminBos = (AddAdminBo) args[0];
                log.setResult(adminBos.getUsername());
            } else if ("编辑管理员".equals(adminLog.action())) {

                UpdateAdminBo adminBos = (UpdateAdminBo) args[0];
                log.setResult(adminBos.getUsername());
            } else if ("删除管理员".equals(adminLog.action())) {

                UpdateAdminBo adminBos = (UpdateAdminBo) args[0];
                log.setResult(adminBos.getUsername());
            }
        }

        log.setAddTime(new Date());
        log.setUpdateTime(new Date());
        logService.insertLogInfo(log);
    }

}
